package gupao.concurrency.simpledemo.risk.service;

import gupao.concurrency.simpledemo.risk.model.Node;
import gupao.concurrency.simpledemo.risk.model.RiskCapitalCalcContext;
import gupao.concurrency.simpledemo.risk.simulator.CalcSimulator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Future;

public class OptLevelConcurrentCalculateServiceImpl extends LevelConcurrentCalculateServiceImpl{

    private static final Log log = LogFactory.getLog(OptLevelConcurrentCalculateServiceImpl.class);

    @Override
    List<NodeCalcTask> generateLevelNodesTask(RiskCapitalCalcContext context, int level) {
        List<Node> levelNodeList = context.getDeptTree().getLevelMap().get(level);
        List<NodeCalcTask> tasks = new ArrayList<>(levelNodeList.size());
        for (Node node : levelNodeList) {
            tasks.add(new OptNodeCalcTask(node, context));
        }
        return tasks;
    }

    @Override
    void infoLog(String msg){
        log.info(msg);
    }

    static
    class OptNodeCalcTask extends NodeCalcTask{
        public OptNodeCalcTask(Node node, RiskCapitalCalcContext context) {
            super(node, context);
        }
        @Override
        public void run() {
            Future<?> f = RiskThreadPoolService.getInstance()
                            .getNodeQafThreadPool().submit(new QafCalcTask(node, context));
            CalcSimulator.calcRiskCaptital(node,context.getDeptTree());
            try {
                f.get();
            } catch (Exception e) {
                context.setLastError(e);
            }
        }
    }

    static class QafCalcTask extends NodeCalcTask {
        public QafCalcTask(Node node, RiskCapitalCalcContext context) {
            super(node, context);
        }

        @Override
        public void run() {
            CalcSimulator.calcNodeQaf(node, context.getDeptTree());
        }
    }
}
